<template>
  <div class="app-container">
    <FHeader :list-query.sync="listQuery" :tags-list="tagsList" :list.sync="list" :idc-list="idcList" :assets-status-dict="assetsStatusDict" :device-type-dict="deviceTypeDict" :server-type-dict="serverTypeDict" @filter="handleFilter" @create="handleCreate" />
    <!--表格渲染-->
    <el-table v-if="checkPermission(['admin','server_list','server_all'])" v-loading="listLoading" :data="list" border size="small" row-key="id" @selection-change="handleSelectionChange">
      <el-table-column type="expand">
        <template slot-scope="props">
          <el-form label-position="left" inline class="table-expand">
            <el-form-item label="次IP">
              <span>{{ props.row.other_ip }}</span>
            </el-form-item>
            <el-form-item label="管理IP">
              <span>{{ props.row.management_ip }}</span>
            </el-form-item>
            <el-form-item label="资产状态">
              <span>{{ props.row.status }}</span>
            </el-form-item>
            <el-form-item label="资产品牌">
              <span>{{ props.row.brand }}</span>
            </el-form-item>
            <el-form-item label="资产型号">
              <span>{{ props.row.model }}</span>
            </el-form-item>
            <el-form-item label="认证类型">
              <span>{{ props.row.auth_type }}</span>
            </el-form-item>
            <el-form-item label="连接端口">
              <span>{{ props.row.port }}</span>
            </el-form-item>
            <el-form-item label="用户名">
              <span>{{ props.row.username }}</span>
            </el-form-item>
            <el-form-item label="密码">
              <span @click="handleCopy(props.row.password,$event)">{{ props.row.password }}</span>
            </el-form-item>
            <el-form-item label="系统类型">
              <span>{{ props.row.os_type }}</span>
            </el-form-item>
            <el-form-item label="设备类型">
              <span>{{ props.row.device_type }}</span>
            </el-form-item>
            <el-form-item label="服务器类型">
              <span>{{ props.row.type }}</span>
            </el-form-item>
            <el-form-item label="应用环境">
              <span>{{ props.row.app_env }}</span>
            </el-form-item>
            <el-form-item label="服务架构">
              <span>{{ props.row.app_desc }}</span>
            </el-form-item>
            <el-form-item label="机房">
              <template v-if="props.row.idc">
                <span>{{ props.row.idc.name }}</span>
              </template>
            </el-form-item>
            <el-form-item label="机柜">
              <span>{{ props.row.cabinet }}</span>
            </el-form-item>
            <el-form-item label="上架日期">
              <span>{{ props.row.shelves_date }}</span>
            </el-form-item>
            <el-form-item label="维保日期">
              <span>{{ props.row.maintenance_date }}</span>
            </el-form-item>
            <el-form-item label="创建日期">
              <span>{{ props.row.create_date | parseTime('{y}-{m}-{d} {h}:{i}') }}</span>
            </el-form-item>
            <el-form-item label="上次更新">
              <span>{{ props.row.update_date | parseTime('{y}-{m}-{d} {h}:{i}') }}</span>
            </el-form-item>
            <el-form-item label="备注" style="width:100%;">
              <span>{{ props.row.remarks }}</span>
            </el-form-item>
          </el-form>
        </template>
      </el-table-column>
      <el-table-column
        type="selection"
        width="45"
      />
      <el-table-column prop="id" label="ID" align="center" width="50px">
        <template slot-scope="scope">
          <span>{{ scope.row.id }}</span>
        </template>
      </el-table-column>
      <el-table-column prop="ip" label="IP地址" align="center" width="150%">
        <template slot-scope="scope">
          <span style="color:#409EFF;" @click="handleCopy(scope.row.ip,$event)">{{ scope.row.ip }}</span>
        </template>
      </el-table-column>
      <el-table-column prop="name" label="SN" align="center" width="100%">
        <template slot-scope="scope">
          <span @click="handleCopy(scope.row.sn,$event)">{{ scope.row.sn }}</span>
        </template>
      </el-table-column>
      <el-table-column prop="security_domain" label="安全域" width="100%" align="center">
        <template slot-scope="scope">
          <span>{{ scope.row.security_domain }}</span>
        </template>
      </el-table-column>
      <el-table-column prop="app" align="center" label="应用">
        <template slot-scope="scope">
          <span>{{ scope.row.app }}</span>
        </template>
      </el-table-column>
      <el-table-column prop="os_version" align="center" width="120%" label="系统版本">
        <template slot-scope="scope">
          <svg-icon v-if="scope.row.os_type=='LINUX'" slot="prefix" style="height:1.5em;width:1.5em;" icon-class="centOS" />
          <svg-icon v-if="scope.row.os_type=='WINDOWS'" slot="prefix" style="height:1.5em;width:1.5em;" icon-class="Windows" />
          <svg-icon v-if="scope.row.os_type=='AIX'" slot="prefix" style="margin:left;height:1.5em;width:1.5em;" icon-class="AIX" />
          <svg-icon v-if="scope.row.os_type=='ESXI'" slot="prefix" style="margin:left;height:1.5em;width:1.5em;" icon-class="vmware" />
          <span>{{ scope.row.os_version }}</span>
        </template>
      </el-table-column>
      <el-table-column prop="tags" align="center" label="标签">
        <template slot-scope="scope">
          <template v-for="tag in scope.row.tags">
            <el-tag :key="tag.id" size="small" type="success" style="margin:5px;">
              {{ tag.name }}
            </el-tag>
          </template>
        </template>
      </el-table-column>
      <el-table-column label="操作" width="235%" align="center">
        <template slot-scope="scope">
          <el-button v-if="scope.row.auth_type=='SSH'" type="warning" size="mini" @click="handleSSH(scope.row)">
            SSH
          </el-button>
          <el-button v-if="scope.row.auth_type=='RDP'" type="warning" size="mini" @click="handleRDP(scope.row)">
            RDP
          </el-button>
          <el-button v-if="checkPermission(['admin','server_edit','server_all'])" type="primary" size="mini" @click="handleUpdate(scope.row)">
            编辑
          </el-button>
          <el-button v-if="checkPermission(['admin','server_delete','server_all'])" type="danger" size="mini" @click="handleDelete(scope.row)">
            删除
          </el-button>
        </template>
      </el-table-column>
    </el-table>
    <!--分页组件-->
    <pagination
      v-show="total>0"
      :total="total"
      :page.sync="listQuery.page"
      :page-sizes="[10, 30, 50, 100,999]"
      :limit.sync="listQuery.limit"
      @pagination="getList"
    />
    <el-dialog :title="textMap[dialogStatus]" :before-close="handleClose" :visible.sync="dialogFormVisible" width="60%">
      <el-form ref="dataForm" :model="form" :inline="true" label-position="right" size="small" :rules="rules" label-width="100px">
        <el-form-item label="IP地址" prop="ip">
          <el-input v-model="form.ip" style="width:150px" />
        </el-form-item>
        <el-form-item label="次IP" prop="other_ip">
          <el-input v-model="form.other_ip" style="width:150px" />
        </el-form-item>
        <el-form-item label="管理IP" prop="management_ip">
          <el-input v-model="form.management_ip" style="width:150px" />
        </el-form-item>
        <el-form-item label="安全域" prop="security_domain">
          <el-select v-model="form.security_domain" style="width:150px" placeholder="请选择">
            <el-option
              v-for="item in securityDomainDict"
              :key="item.value"
              :label="item.label"
              :value="item.value"
            />
          </el-select>
        </el-form-item>
        <el-form-item label="资产状态" prop="status">
          <el-select v-model="form.status" placeholder="请选择" style="width:150px">
            <el-option
              v-for="item in assetsStatusDict"
              :key="item.value"
              :label="item.value"
              :value="item.value"
            />
          </el-select>
        </el-form-item>
        <el-form-item label="资产型号" prop="model">
          <el-input v-model="form.model" style="width:150px" />
        </el-form-item>
        <el-form-item label="系统类型" prop="os_type">
          <el-select v-model="form.os_type" style="width:150px" placeholder="请选择" @change="handleOsTypeSelected">
            <el-option
              v-for="item in os_type_dict"
              :key="item.value"
              :label="item.label"
              :value="item.value"
            />
          </el-select>
        </el-form-item>
        <el-form-item label="设备类型" prop="device_type">
          <el-select v-model="form.device_type" style="width:150px" placeholder="请选择">
            <el-option
              v-for="item in deviceTypeDict"
              :key="item.value"
              :label="item.label"
              :value="item.value"
            />
          </el-select>
        </el-form-item>
        <el-form-item label="服务器类型" prop="type">
          <el-select v-model="form.type" style="width:150px" placeholder="请选择">
            <el-option
              v-for="item in serverTypeDict"
              :key="item.value"
              :label="item.value"
              :value="item.value"
            />
          </el-select>
        </el-form-item>
        <el-form-item label="端口" prop="port">
          <el-input v-model="form.port" style="width:150px" />
        </el-form-item>
        <el-form-item label="用户名" prop="username">
          <el-input v-model="form.username" style="width:150px" />
        </el-form-item>
        <el-form-item label="密码" prop="password">
          <el-input v-model="form.password" style="width:150px" />
        </el-form-item>
        <el-form-item label="认证类型" prop="auth_type">
          <el-select v-model="form.auth_type" style="width:150px" placeholder="请选择">
            <el-option
              v-for="item in auth_type_dict"
              :key="item.value"
              :label="item.label"
              :value="item.value"
            />
          </el-select>
        </el-form-item>
        <el-form-item label="资产SN" prop="sn">
          <el-input v-model="form.sn" style="width:150px" />
        </el-form-item>
        <el-form-item label="资产品牌" prop="brand">
          <el-input v-model="form.brand" style="width:150px" />
        </el-form-item>
        <el-form-item label="应用环境" prop="app_env">
          <el-select v-model="form.app_env" style="width:150px" placeholder="请选择">
            <el-option
              v-for="item in environment_dict"
              :key="item.value"
              :label="item.label"
              :value="item.value"
            />
          </el-select>
        </el-form-item>
        <el-form-item label="应用" prop="app">
          <el-input v-model="form.app" style="width:150px" />
        </el-form-item>
        <el-form-item label="服务架构" prop="app_desc">
          <el-input v-model="form.app_desc" style="width:150px" />
        </el-form-item>
        <el-form-item label="IDC机房" prop="idc">
          <el-select v-model="form.idc" placeholder="请选择" style="width:150px">
            <el-option
              v-for="item in idcList"
              :key="item.id"
              :label="item.name"
              :value="item.id"
            />
          </el-select>
        </el-form-item>
        <el-form-item label="机柜" prop="cabinet">
          <el-input v-model="form.cabinet" style="width:150px" />
        </el-form-item>
        <el-form-item label="系统版本" prop="os_version">
          <el-input v-model="form.os_version" style="width:150px" />
        </el-form-item>
        <el-form-item label="上架日期" prop="shelves_date">
          <el-date-picker
            v-model="form.shelves_date"
            style="width:150px"
            type="date"
            placeholder="选择日期"
            format="yyyy-MM-dd"
            value-format="yyyy-MM-dd"
          />
        </el-form-item>
        <el-form-item label="维保日期" prop="maintenance_date">
          <el-date-picker
            v-model="form.maintenance_date"
            type="date"
            style="width:150px"
            placeholder="选择日期"
            format="yyyy-MM-dd"
            value-format="yyyy-MM-dd"
          />
        </el-form-item>
        <el-form-item label="资产标签" prop="tags">
          <el-select v-model="form.tags" multiple style="width:460px;" placeholder="请选择">
            <el-option
              v-for="item in tagsList"
              :key="item.id"
              :label="item.name"
              :value="item.id"
            />
          </el-select>
        </el-form-item>
        <el-row>
          <el-col>
            <el-form-item label="备注" prop="remarks">
              <el-input v-model="form.remarks" :rows="4" style="width:650px" type="textarea" />
            </el-form-item>
          </el-col>
        </el-row>
      </el-form>
      <div slot="footer" class="dialog-footer">
        <el-button @click="dialogFormVisible = false">
          取消
        </el-button>
        <el-button type="primary" @click="dialogStatus==='create'?createData():updateData()">
          确认
        </el-button>
      </div>
    </el-dialog>
    <el-dialog :title="sshTitle" width="50%" :before-close="handleCloseSSH" destroy-on-close custom-class="dialog" :visible.sync="sshDialog" top="10px">
      <div class="term-body">
        <div ref="terminal" class="console" />
      </div>
    </el-dialog>

  </div>
</template>

<script>
import Pagination from '@/components/Pagination'
import checkPermission from '@/utils/permission'
import { getToken } from '@/utils/auth'
import { getTags } from '@/api/tags'
import { getDictByKey } from '@/api/dict'
import clip from '@/utils/clipboard'
import { getServers, delServer, addServer, editServer } from '@/api/server'
import Terminal from './components/Xterm'
import 'xterm/dist/xterm.css'
import { getIdc } from '@/api/idc'
import FHeader from './components/FilterHeader'
export default {
  name: 'Server',
  components: { Pagination, FHeader },
  data() {
    return {
      list: null,
      total: 0,
      dialogFormVisible: false,
      dialogStatus: '',
      drawer: false,
      textMap: {
        update: '更新主机',
        create: '新增主机'
      },
      tagsList: [],
      idcList: [],
      serverTypeDict: [],
      assetsStatusDict: [],
      sshTitle: '',
      os_type_dict: [],
      sshDialog: false,
      terminalContainer: null,
      deviceTypeDict: [],
      term: null,
      terminalSocket: null,
      securityDomainDict: [],
      environment_dict: [],
      auth_type_dict: [],
      listLoading: true,
      form: {
        id: '',
        port: '22',
        tags: []
      },
      rules: {
        ip: [
          { required: true, message: 'IP不能为空', trigger: 'blur' }
        ],
        security_domain: [
          { required: true, message: '请选择安全域', trigger: 'blur' }
        ],
        status: [
          { required: true, message: '请选择资产状态', trigger: 'blur' }
        ],
        type: [
          { required: true, message: '请选择服务器类型', trigger: 'blur' }
        ],
        device_type: [
          { required: true, message: '请选择设备类型', trigger: 'blur' }
        ],
        os_type: [
          { required: true, message: '请选择操作系统类型', trigger: 'blur' }
        ]
      },
      listQuery: {
        page: 1,
        limit: 10,
        search: undefined
      },
      message: {
        'status': 0,
        'data': null,
        'cols': null,
        'rows': null
      }
    }
  },
  created() {
    this.$nextTick(() => {
      this.getList()
      this.getTags()
      this.getIdc()
      this.getDicts()
    })
  },
  methods: {
    checkPermission,
    handleSSH(row) {
      if (row.auth_type !== 'SSH' || row.os_type === 'WINDOWS') {
        this.$message.warning('仅支持SSH服务的服务器')
        return
      }
      this.sshDialog = true
      this.sshTitle = row.ip
      const protocol = (location.protocol === 'https:') ? 'wss://' : 'ws://'
      const socketURL = protocol + location.hostname + ((location.port) ? (':' + location.port) : '') +
      '/websocket/console?&width=70&height=30&id=' + row.id + '&token=' + getToken()
      this.term = new Terminal(
        {
          cols: 75,
          rows: 30,
          useStyle: true,
          tabStopWidth: 4,
          convertEol: true,
          cursorBlink: true, // 光标闪烁
          theme: {
            foreground: 'yellow', // 字体
            background: '#111' // 背景色
          }
        }
      )
      const _this = this
      this.$nextTick(() => {
        this.terminalSocket = new WebSocket(socketURL)
        this.terminalContainer = this.$refs.terminal
        this.term.open(this.terminalContainer)
        this.term.writeln('WELCOME TO OPS WEB SSH')
        this.term.focus()
        this.term._initialized = true
        this.terminalSocket.addEventListener('message', function(recv) {
          var data = JSON.parse(recv.data)
          var message = data.message
          var status = data.status
          if (status === 0) {
            _this.term.write(message)
          }
          if (status === 2) {
            _this.$message.error(message)
          }
        })
        this.term.on('data', function(data) {
          _this.message['status'] = 0
          _this.message['data'] = data
          var send_data = JSON.stringify(_this.message)
          _this.terminalSocket.send(send_data)
        })
        this.terminalSocket.onopen = this.runRealTerminal
      })
    },
    handleRDP(row) {
      this.$router.push({
        path: '/assets/server/guacamole',
        query: {
          id: row.id,
          token: getToken(),
          info: row.ip + ' ' + row.app
        }
      })
      // const { href } = this.$router.resolve({
      //   path: '/assets/server/guacamole',
      //   query: {
      //     id: row.id,
      //     token: getToken()
      //   }
      // })
      // window.open(href, '_blank')
    },
    runRealTerminal() {
      this.$message({
        type: 'success',
        message: '已建立websocket链接!'
      })
    },
    getIdc() {
      getIdc().then(response => {
        this.idcList = response
      })
    },
    getDicts() {
      const key = [
        'SERVER_TYPE',
        'OS_TYPE',
        'AUTH_TYPE',
        'ASSETS_STATUS',
        'SECURITY_DOMAIN',
        'ENVIRONMENT',
        'DEVICE_TYPE'
      ]
      getDictByKey(key).then(response => {
        for (const i of response) {
          if (i.SERVER_TYPE != null) { this.serverTypeDict = i.SERVER_TYPE }
          if (i.ASSETS_STATUS != null) { this.assetsStatusDict = i.ASSETS_STATUS }
          if (i.OS_TYPE != null) { this.os_type_dict = i.OS_TYPE }
          if (i.AUTH_TYPE != null) { this.auth_type_dict = i.AUTH_TYPE }
          if (i.SECURITY_DOMAIN != null) { this.securityDomainDict = i.SECURITY_DOMAIN }
          if (i.ENVIRONMENT != null) { this.environment_dict = i.ENVIRONMENT }
          if (i.DEVICE_TYPE != null) { this.deviceTypeDict = i.DEVICE_TYPE }
        }
      })
    },
    getTags() {
      getTags().then(response => {
        this.tagsList = response
      })
    },
    getList() {
      getServers(this.listQuery).then(response => {
        this.list = response.results
        this.total = response.count
        this.listLoading = false
        // Just to simulate the time of the request
        // setTimeout(() => {
        //   this.listLoading = false
        // }, 170)
      })
    },
    handleFilter() {
      this.listQuery.page = 1
      this.listQuery.limit = 10
      this.listLoading = true
      this.getList()
    },
    handleSelectionDel() {
      const resultArr = []
      this.multipleSelection.forEach(function(data, index) {
        const result = delServer(data.id).catch(err => {
          console.log(err)
        })
        resultArr.push(result)
      })
      Promise.all(resultArr).then((resultArr) => {
        this.handleFilter()
      })
    },
    handleDelete(row) {
      this.$confirm('此操作将永久删除此行, 是否继续?', '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      }).then(() => {
        delServer(row.id).then(response => {
          this.$message({
            type: 'success',
            message: '删除成功!'
          })
          const index = this.list.indexOf(row)
          this.list.splice(index, 1)
          this.handleFilter()
        })
      }).catch(() => {
        this.$message({
          type: 'info',
          message: '已取消删除'
        })
      })
    },
    handleSelectionChange(val) {
      this.multipleSelection = val
    },
    handleOsTypeSelected(val) {
      // 判断当前为新建状态
      if (this.dialogStatus === 'create') {
        if (val === 'WINDOWS') {
          this.form.username = 'administrator'
          this.form.port = '9989'
          this.form.auth_type = 'RDP'
        } else {
          this.form.username = 'root'
          this.form.port = '22'
          this.form.auth_type = 'SSH'
        }
      }
    },
    handleCopy(text, event) {
      clip(text, event)
    },
    resetForm() {
      this.form = {
        id: '',
        app: '',
        app_desc: '',
        app_env: '',
        auth_type: '',
        brand: '',
        cabinet: '',
        device_type: '',
        idc: '',
        ip: '',
        maintenance_date: '',
        shelves_date: '',
        management_ip: '',
        model: '',
        os_type: '',
        os_version: '',
        other_ip: '',
        password: '',
        port: '22',
        remarks: '',
        security_domain: '内网',
        sn: '',
        status: '使用中',
        tags: [],
        type: '',
        username: ''
      }
    },
    handleCreate() {
      this.resetForm()
      this.dialogStatus = 'create'
      this.dialogFormVisible = true
      this.$nextTick(() => {
        this.$refs['dataForm'].clearValidate()
      })
    },
    createData() {
      this.$refs['dataForm'].validate((valid) => {
        if (valid) {
          addServer(this.form).then(() => {
            this.resetForm()
            // this.list.unshift(this.temp)
            this.$message({
              type: 'success',
              message: '创建成功!'
            })
            this.dialogFormVisible = false
            this.handleFilter()
          })
        }
      })
    },
    handleClose(done) {
      this.$confirm('确认关闭？')
        .then(_ => {
          done()
        })
        .catch(_ => {})
    },
    handleCloseSSH(done) {
      this.$confirm('确认关闭？')
        .then(_ => {
          this.terminalSocket.close()
          this.term.destroy()
          done()
        })
        .catch(_ => {})
    },
    handleUpdate(row) {
      this.resetForm()
      if (row.idc != null) {
        this.form = { ...row, tags: [], idc: [] }
        this.form.idc = row.idc.id
      } else {
        this.form = { ...row, tags: []
        }
      }
      for (const i of row.tags) {
        this.form.tags.push(i.id)
      }
      this.dialogStatus = 'update'
      this.dialogFormVisible = true
      this.$nextTick(() => {
        // this.$refs['dataForm'].resetFields()
        this.$refs['dataForm'].clearValidate()
      })
    },
    updateData() {
      this.$refs['dataForm'].validate((valid) => {
        if (valid) {
          editServer(this.form.id, this.form).then(() => {
            this.dialogFormVisible = false
            this.handleFilter()
            this.$message({
              type: 'success',
              message: '编辑成功!'
            })
          })
        }
      })
    }
  }
}
</script>
<style scoped>
  .console {
    width:100%;
  }
  .term-body {
      background: rgb(0, 0, 0);
      margin:0 0 0 0px!important;
  }
  .table-expand {
    font-size: 0;
  }
  .table-expand label {
    color: #99a9bf;
    font-size:12px
  }
  .table-expand span {
    color:#606266;
    font-size:12px
  }
  .table-expand .el-form-item {
    margin-right: 0;
    margin-bottom: 0;
    width: 25%;
  }
</style>
<style>
  .dialog {
    background: #111;
  }
  .dialog .el-dialog__header .el-dialog__title{
    color:#fff;
  }
</style>
